package com.szholly.plug.activity.model;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Component;

import com.szholly.utils.util.StringUtils;
import com.szholly.data.general.IQueryMap;
import com.szholly.data.general.ITable;
import com.szholly.data.general.IUpdateMap;
import com.szholly.data.general.QueryMap;
import com.szholly.data.general.RowBase;
import com.szholly.data.general.UpdateMap;
import com.szholly.data.general.interceptor.DbEditInterceptorClass;
import com.szholly.data.general.interceptor.DbEditType;
import com.szholly.data.general.interceptor.InterceptorRegister;
import com.szholly.plug.safe.entity.role.RoleService;
import com.szholly.plug.safe.entity.user.UserEntity;
import com.szholly.plug.safe.entity.user.UserRoleEntity;
import com.szholly.plug.safe.entity.user.UserRoleService;
import com.szholly.plug.safe.entity.user.UserService;

/**
 * 流程配置拦截器，用于清除流程缓存 1.主配置表保存时，清除所有缓存 2.任务节点保存时，重新计算用户配置信息
 * 3.用户保存时，清除任务节点配置的用户配置信息(包括缓存信息和数据库信息) 4.任务配置使用时，实时调用验证
 */
@Component
public class BpmConfigEditInterceptor extends DbEditInterceptorClass {
	/**
	 * 注册拦截接口
	 */
	static {
		BpmConfigEditInterceptor interceptor = new BpmConfigEditInterceptor();
		InterceptorRegister.RegDbInterceptor(interceptor);
	}

	public BpmConfigEditInterceptor() {
		this.regTableName(BpmConfigTable.TABLE_NAME);
		this.regTableName(BpmTaskConfigTable.TABLE_NAME);
		this.regTableName(UserService.TABLE_NAME);
		this.regTableName(RoleService.TABLE_NAME);
	}

	@Override
	public void BeforeDbEditOption(ITable table, Object editEntitys,
			DbEditType editType) {

		// 2.任务节点保存时，重新计算用户配置信息
		if (table.getMetadataTableName().equals(BpmTaskConfigTable.TABLE_NAME)) {
			if (editEntitys instanceof RowBase
					&& (editType == DbEditType.Update || editType == DbEditType.Insert)) {
				RowBase taskConfigRow = (RowBase) editEntitys;
				BpmTaskConfigRow row = new BpmTaskConfigRow();
				row.putAll(taskConfigRow);
				String userExpress = getUserExpress(row);
				taskConfigRow.setValue(BpmTaskConfigRow.FIELD_USEREXPRESS,
						userExpress);
			}
			if (editEntitys instanceof ArrayList
					&& editType == DbEditType.Update) {
				@SuppressWarnings("unchecked")
				List<Object> arr = (ArrayList<Object>) editEntitys;
				for (int i = 0; i < arr.size(); i++) {
					if (arr.get(i) instanceof RowBase) {
						RowBase taskConfigRow = (RowBase) arr.get(i);
						BpmTaskConfigRow row = new BpmTaskConfigRow();
						row.putAll(taskConfigRow);
						String userExpress = getUserExpress(row);
						taskConfigRow
								.setValue(BpmTaskConfigRow.FIELD_USEREXPRESS,
										userExpress);
					}
				}
			}
		}
	}

	@Override
	public void DbEditOptionException(ITable table, Object editEntitys,
			DbEditType editType, Exception ex) {
	}

	@Override
	public void AfterDbEditOption(ITable table, Object editEntitys,
			DbEditType editType) {
		// 1.主配置表保存时，清除所有缓存
		if (table.getMetadataTableName().equals(BpmConfigTable.TABLE_NAME)) {
			BpmConfigCache.reInit();
		}

		// 3.用户保存时，清除任务节点配置的用户配置信息(包括缓存信息和数据库信息)
		if (table.getMetadataTableName().equals(UserService.TABLE_NAME)
				|| table.getMetadataTableName().equals(RoleService.TABLE_NAME)) {
			// 更新数据库
			IUpdateMap updateMap = new UpdateMap();
			updateMap.getSetMap().put(BpmTaskConfigRow.FIELD_USEREXPRESS, "");
			BpmTaskConfigTable.getSingleRef().update(updateMap);

			BpmConfigCache.reInit();
		}
	}

	@Override
	public String getInterceptorName() {
		return "流程配置拦截器，用于清除流程缓存";
	}

	/**
	 * 获取解释后的用户表达式
	 * 
	 * @param taskConfig
	 */
	public static String getUserExpress(BpmTaskConfigRow taskConfig) {
		List<String> userList = new ArrayList<String>();
		// 获取配置的用户
		String taskUser = taskConfig.getTaskUser();
		if (!StringUtils.IsNullOrSpace(taskUser)) {
			String[] users = taskUser.split(",");
			for (String user : users) {
				if (!StringUtils.IsNullOrSpace(user)
						&& !userList.contains(user)) {
					userList.add(user);
				}
			}
		}

		// 从获取配置的角色中，获取所有用户
		String taskRole = taskConfig.getTaskRole();
		if (!StringUtils.IsNullOrSpace(taskRole)) {
			String[] roles = taskRole.split(",");
			String whereString = "";
			for (String role : roles) {
				whereString += "'" + role + "',";
			}
			whereString = whereString.substring(0, whereString.length() - 1);
			IQueryMap queryMap = new QueryMap();
			queryMap.setSelectFields(UserRoleEntity.FIELD_USERID);
			queryMap.getWhereMap().put(UserRoleEntity.FIELD_ROLEID + ":in",
					whereString);
			List<UserRoleEntity> rowList = UserRoleService.getSingleRef()
					.getEntityList(UserRoleEntity.class, queryMap);
			if (rowList != null) {
				for (UserRoleEntity item : rowList) {
					String user = item.getUserID();
					if (!StringUtils.IsNullOrSpace(user)
							&& !userList.contains(user)) {
						userList.add(user);
					}
				}
			}
		}

		if (userList.size() > 0) {
			// 从用户中获取用户的性名和所在部门
			String whereString = "";
			for (String userid : userList) {
				whereString += "'" + userid + "',";
			}
			whereString = whereString.substring(0, whereString.length() - 1);

			IQueryMap queryMap = new QueryMap();
			queryMap.setSelectFields(UserEntity.FIELD_USERID + ","
					+ UserEntity.FIELD_ORGID + ","
					+ UserEntity.FIELD_C_USEREALNAME + ","
					+ UserEntity.FIELD_DEPTID + "," + UserEntity.FIELD_ZQID);
			queryMap.getWhereMap().put(UserEntity.FIELD_USERID + ":in",
					whereString);
			List<UserEntity> userEntitys = UserService.getSingleRef()
					.getEntityList(UserEntity.class, queryMap);

			if (userEntitys != null && userEntitys.size() > 0) {
				String userExpress = "";
				for (UserEntity userEntity : userEntitys) {
					userExpress += userEntity.getUserID() + ","
							+ userEntity.getUserRealName() + ","
							+ userEntity.getOrgID() + ","
							+ userEntity.getDEPTID() + ","
							+ userEntity.getZqID() + ",";
				}
				userExpress = userExpress
						.substring(0, userExpress.length() - 1);
				return userExpress;
			} else {
				return "";
			}
		} else {
			return "";
		}
	}

	/**
	 * 更新节点配置的用户表达式
	 * 
	 * @param taskConfig
	 * @param userExpress
	 * @return
	 */
	public static void updateTaskUserExpress(BpmTaskConfigRow taskConfig,
			String userExpress) {
		IUpdateMap updateMap = new UpdateMap();
		updateMap.getSetMap().put(BpmTaskConfigRow.FIELD_USEREXPRESS,
				userExpress);
		updateMap.getWhereMap().put(BpmTaskConfigRow.FIELD_GUID,
				taskConfig.getValue(BpmTaskConfigRow.FIELD_GUID));
		BpmTaskConfigTable.getSingleRef().update(updateMap);
	}
}